﻿using System;
using System.Collections.Generic;
using System.Linq;
using DotNetNuke.Common.Utilities;
//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by DotNetNuke Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
using DotNetNuke.Entities.Content.Common;
using DotNetNuke.Entities.Modules;
using System.Xml.Serialization;

namespace DotNetNuke.Entities.Content.Taxonomy
{

    [Serializable()]
    public class Term : BaseEntityInfo, IHydratable
    {

        #region "Private Members"

        private List<Term> _ChildTerms;
        private string _Description;
        private int _Left;
        private string _Name;
        private Nullable<int> _ParentTermId;
        private int _Right;
        private List<string> _Synonyms;
        private int _TermId;
        private Vocabulary _Vocabulary;
        private int _VocabularyId;

        private int _Weight;
        #endregion

        #region "Constructors"

        public Term()
            : this(Null.NullString, Null.NullString, Null.NullInteger)
        {
        }

        public Term(int vocabularyId)
            : this(Null.NullString, Null.NullString, vocabularyId)
        {
        }

        public Term(string name)
            : this(name, Null.NullString, Null.NullInteger)
        {
        }

        public Term(string name, string description)
            : this(name, description, Null.NullInteger)
        {
        }

        public Term(string name, string description, int vocabularyId)
        {
            _Description = description;
            _Name = name;
            _VocabularyId = vocabularyId;

            _ParentTermId = null;
            _TermId = Null.NullInteger;
            _Left = 0;
            _Right = 0;
            _Weight = 0;
        }

        #endregion

        #region "Public Properties"

        [XmlIgnore]
        public List<Term> ChildTerms
        {
            get
            {
                if (_ChildTerms == null)
                {
                    _ChildTerms = this.GetChildTerms(_TermId, _VocabularyId);
                }
                return _ChildTerms;
            }
        }

        [XmlIgnore]
        public string Description
        {
            get { return _Description; }
            set { _Description = value; }
        }

        [XmlIgnore]
        public bool IsHeirarchical
        {
            get { return (Vocabulary.Type == VocabularyType.Hierarchy); }
        }

        [XmlIgnore]
        public int Left
        {
            get { return _Left; }
        }

        [XmlIgnore]
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        [XmlIgnore]
        public Nullable<int> ParentTermId
        {
            get { return _ParentTermId; }
            set { _ParentTermId = value; }
        }

        [XmlIgnore]
        public int Right
        {
            get { return _Right; }
        }

        [XmlIgnore]
        public List<string> Synonyms
        {
            get { return _Synonyms; }
        }

        [XmlIgnore]
        public int TermId
        {
            get { return _TermId; }
            set { _TermId = value; }
        }

        [XmlIgnore]
        public Vocabulary Vocabulary
        {
            get
            {
                if (_Vocabulary == null && _VocabularyId > Null.NullInteger)
                {
                    _Vocabulary = this.GetVocabulary(_VocabularyId);
                }
                return _Vocabulary;
            }
        }

        [XmlIgnore]
        public int VocabularyId
        {
            get { return _VocabularyId; }
        }

        [XmlIgnore]
        public int Weight
        {
            get { return _Weight; }
            set { _Weight = value; }
        }

        #endregion

        #region "IHydratable Implementation"

        public virtual void Fill(System.Data.IDataReader dr)
        {
            TermId = Null.SetNullInteger(dr["TermID"]);
            Name = Null.SetNullString(dr["Name"]);
            Description = Null.SetNullString(dr["Description"]);
            Weight = Null.SetNullInteger(dr["Weight"]);
            _VocabularyId = Null.SetNullInteger(dr["VocabularyID"]);

            if (dr["TermLeft"] != DBNull.Value)
            {
                _Left = Convert.ToInt32(dr["TermLeft"]);
            }
            if (dr["TermRight"] != DBNull.Value)
            {
                _Right = Convert.ToInt32(dr["TermRight"]);
            }
            if (dr["ParentTermID"] != DBNull.Value)
            {
                ParentTermId = Convert.ToInt32(dr["ParentTermID"]);
            }

            //Fill base class properties
            FillInternal(dr);
        }

        public int KeyID
        {
            get { return TermId; }
            set { TermId = value; }
        }

        #endregion

        public string GetTermPath()
        {
            string path = "\\\\" + Name;

            if (ParentTermId.HasValue)
            {
                ITermController ctl = Util.GetTermController();

                Term parentTerm = (from t in ctl.GetTermsByVocabulary(VocabularyId)
                                   where t.TermId == ParentTermId
                                   select t).SingleOrDefault();

                if (parentTerm != null)
                {
                    path = parentTerm.GetTermPath() + path;
                }
            }
            return path;
        }


    }

}

